package contact.view;

import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletContext;

import model.db.Annotation;
import model.db.Query;
import model.db.User;
import model.db.Vertical;
import model.db.VerticalResult;

import org.apache.struts2.interceptor.SessionAware;
import org.apache.struts2.util.ServletContextAware;

import util.hashing.Sorting;
import util.math.RandomElement;

import com.opensymphony.xwork2.ActionSupport;

import contact.controller.AssesmentManager;
import contact.controller.QueryManager;
import contact.controller.UserManager;
import contact.controller.VerticalManager;
import contact.controller.VerticalResultsManager;
import contact.view.util.SurveyLogic;

public class SurveyAction extends ActionSupport implements SessionAware,ServletContextAware {

	private static final long serialVersionUID = 9149826260758390091L;

	private User user ;
	private List<Query> query_list=null;
	private Long id;
	
	private Query q;

	private Vertical left_vertical;
	private Vertical right_vertical;
	
	
	private String result_type_left=null;
	private String result_type_right=null;
	
	
	
	

	
	
public Query getQ() {
	return q;
}


public void setQ(Query q) {
	this.q = q;
}
	public String getResult_type_right() {
		result_type_right= SurveyLogic.classifyResultType(this.right_vertical);
		
		System.out.println("PRINTING RESULT RIGHT TYPE:"+ result_type_right);
		
		return result_type_right;
		
	}

	public String getResult_type_left() {
		

		result_type_left= SurveyLogic.classifyResultType(this.left_vertical);
		
		System.out.println("PRINTING RESULT LEFT TYPE:"+ result_type_left);
		
		return result_type_left;
		
		
	}

	 public Vertical getLeft_vertical() {
		return left_vertical;
	}


	public void setLeft_vertical(Vertical left_vertical) {
		this.left_vertical = left_vertical;
	}


	public Vertical getRight_vertical() {
		return right_vertical;
	}


	public void setRight_vertical(Vertical right_vertical) {
		this.right_vertical = right_vertical;
	}

	// For SessionAware
	Map<String, Object> session;
	ServletContext servletContext;
	
	private UserManager userManager;
 
	private Annotation assesment;
	
	public Annotation getAssesment() {
		return assesment;
	}


	public void setAssesment(Annotation assesment) {
		this.assesment = assesment;
	}

	private QueryManager queryManager;
	
	private VerticalManager verticalManager;
	private VerticalResultsManager verticalResultsManager;
	
	private AssesmentManager assesmentManager;
	
	private List<VerticalResult> left_results;
	private List<VerticalResult> right_results;
	
	public SurveyAction() {
		
		userManager= new UserManager();
		assesmentManager= new AssesmentManager();
		
		verticalResultsManager= new VerticalResultsManager();
		
		 	
	}
	
	
	


	public List<VerticalResult> getLeft_results() {
		return left_results;
	}


	public void setLeft_results(List<VerticalResult> left_results) {
		this.left_results = left_results;
	}


	public List<VerticalResult> getRight_results() {
		return right_results;
	}


	public void setRight_results(List<VerticalResult> right_results) {
		this.right_results = right_results;
	}


	public List<Query> getQuery_list() {
		return query_list;
	}

	public void setQuery_list(List<Query> query_list) {
		this.query_list = query_list;
	}
	
	

	public String execute() {
		
		System.out.println("Entro a execute SurveyAction");
		
		return SUCCESS;
	}
	
	
	
	

	public String  startQuery(){
		
		try {
			
			//init query
			
			if(!verifyLogin()){
				
				return SurveyLogic.ACTION_LOGIN;
			}
			
			//check if there are still verticals to be evaulated
			if(session.containsKey(SurveyLogic.SESSION_VERTICAL_HASH)){
				
				
				
				Hashtable<Long, ArrayList<VerticalResult>> organized =(Hashtable<Long, ArrayList<VerticalResult>>) session.get(SurveyLogic.SESSION_VERTICAL_HASH);
				 ArrayList<long[]> sequence = (ArrayList<long[]>) session.get(SurveyLogic.SESSION_SEQUENCE);
					
				
				if(sequence.size()>0){
					
					this.q= (Query) session.get(SurveyLogic.SESSION_QUERY);
					this.left_results= (ArrayList<VerticalResult>) session.get(SurveyLogic.SESSION_LEFT_RESULTS);
					this.right_results = (ArrayList<VerticalResult>) session.get(SurveyLogic.SESSION_RIGHT_RESULTS);
					this.user= (User) session.get(SurveyLogic.USER);
					
					SurveyLogic.assignCurrentVerticalDescriptions(servletContext,session,left_results,right_results);
					
					
					
					this.left_vertical= (Vertical) session.get(SurveyLogic.LEFT_VERTICAL);
					this.right_vertical= (Vertical)session.get(SurveyLogic.RIGHT_VERTICAL);
					
					
					
					return SurveyLogic.ACTION_SURVEY;
					
				}
			}
			
			
			
			System.out.println("SurveyAction StartQuery metod ---------");
			SurveyLogic.cleanSessionData(session);
			this.q= SurveyLogic.getNextQuery(servletContext, queryManager, session);
			
			System.out.println("Printing query info");
			
			System.out.println("----" + "\t"+ q.getQuery());
			
		//	SurveyLogic.printQueryList(servletContext);
			//SurveyLogic.printQueryCounts(servletContext);
			
			
			
			
			
			
			
			this.session.put(SurveyLogic.LOGIN, SurveyLogic.LOGIN_ACTIVE);
			this.session.put(SurveyLogic.SESSION_QUERY, q);
			
			SurveyLogic.getNextVerticalResults(q.getId(), verticalResultsManager, session, SurveyLogic.AGAINTS_GOOGLE);
			
			this.left_results= (ArrayList<VerticalResult>) session.get(SurveyLogic.SESSION_LEFT_RESULTS);
			this.right_results = (ArrayList<VerticalResult>) session.get(SurveyLogic.SESSION_RIGHT_RESULTS);
			
			
			SurveyLogic.assignCurrentVerticalDescriptions(servletContext,session,left_results,right_results);
			
			this.left_vertical= (Vertical) session.get(SurveyLogic.LEFT_VERTICAL);
			this.right_vertical= (Vertical)session.get(SurveyLogic.RIGHT_VERTICAL);
			
			
			SurveyLogic.printLeftWebResult(session);
			
			System.out.println("End of surveaction StartQuery method ------------");
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	
		
		return SUCCESS;
		
	}
	
	public String logout() {
		
		session.remove(SurveyLogic.LOGIN);
		SurveyLogic.cleanSessionData(session);
		
		return SUCCESS;
		
	}

	public String register() {
		
			if(!verifyLogin()){
				
				return SurveyLogic.ACTION_LOGIN;
			}
			
		this.user= (User) session.get(SurveyLogic.USER);
		
		left_results=(List<VerticalResult>) session.get(SurveyLogic.SESSION_LEFT_RESULTS);
		right_results= (List<VerticalResult>) session.get(SurveyLogic.SESSION_RIGHT_RESULTS);
		this.q= (Query) session.get(SurveyLogic.SESSION_QUERY);
		SurveyLogic.assignCurrentVerticalDescriptions(servletContext,session,left_results,right_results);
		
		
		this.left_vertical= (Vertical) session.get(SurveyLogic.LEFT_VERTICAL);
		this.right_vertical= (Vertical)session.get(SurveyLogic.RIGHT_VERTICAL);
		
		
		
		if( getAssesment()==null ){
			
			
			session.put("missing_value","true");
			
			return SurveyLogic.ACTION_SURVEY;
		}
		
		if( getAssesment()!=null && getAssesment().getScore()==-1 ){
			
			return SurveyLogic.ACTION_SURVEY;
		}
		
		VerticalResult v_left= left_results.get(0);
		VerticalResult v_right= right_results.get(0);
		
		assesment.setVertical_id_left(v_left.getVertical_id());
		
		assesment.setVertical_id_right(v_right.getVertical_id());
		
		assesment.setQuery_id(v_left.getQuery_id());
		
		assesment.setGrade(assesment.getScore());
		
		String compose_vertical_id= v_left.getVertical_id() + "\t"+ v_right.getVertical_id();
		
		
		assesment.setUser_id(user.getId());
		
		
		Date end_time = new Date();
		
		Date start_time = (java.util.Date) session.get(SurveyLogic.START_TIME);
		assesment.setStart_time(start_time);
		assesment.setEnd_time(end_time);
		
		
		System.out.println("Registering: "+  start_time.getTime() + "\t" + end_time.getTime()  + "\t" + (end_time.getTime()-start_time.getTime()));
		
		session.put("missing_value","false");
		assesmentManager.add(assesment);
		session.remove("reloads");
		
		//Adding 
		
		
		
		/*** add count to query **/
		
	
		SurveyLogic.incrementQueryCount(servletContext, q.getId());
		
		
		System.out.println("Before prepareNextResult");
		SurveyLogic.printLeftWebResult(session);
		
		String status = prepareNextResults();
		
		
		
		
		System.out.println("A prepareNextResult");
		SurveyLogic.printLeftWebResult(session);
		
		return status;
	}
	
	
	
	private boolean verifyLogin() {
			// TODO Auto-generated method stub
			
		
		if(session.containsKey(SurveyLogic.LOGIN) && ((String)session.get(SurveyLogic.LOGIN)).equals(SurveyLogic.LOGIN_ACTIVE)){
			
			return true;
		}
		
		
		
		return false;
	}


	/**
	 * remove current list of results at position 0
	 * if it was the last set of vertical results send
	 * message to the user saying that the query is over 
	 * otherwise just remove and return success
	 * 
	 * 
	 * @return
	 */
	private String prepareNextResults() {
		// TODO Auto-generated method stub
		
		
		
		Hashtable<Long, ArrayList<VerticalResult>> organized =(Hashtable<Long, ArrayList<VerticalResult>>) session.get(SurveyLogic.SESSION_VERTICAL_HASH);
		ArrayList<long[]> sequence = (ArrayList<long[]>) session.get(SurveyLogic.SESSION_SEQUENCE);
			
	
		
		
		
		sequence.remove(0);
		if(sequence.size()==0){
			
			
			SurveyLogic.cleanSessionData(session);
			return "end";
		}
		
		 long[] vertical_ids = sequence.get(0);
			
		 this.left_results = organized.get(vertical_ids[0]);
		 this.right_results = organized.get(vertical_ids[1]);
			
		 session.put(SurveyLogic.SESSION_LEFT_RESULTS, left_results);
		
		 session.put(SurveyLogic.SESSION_RIGHT_RESULTS, right_results);
	
		
		SurveyLogic.assignCurrentVerticalDescriptions(servletContext,session,left_results,right_results);
		this.q= (Query) session.get(SurveyLogic.SESSION_QUERY);
			
		this.left_vertical= (Vertical) session.get(SurveyLogic.LEFT_VERTICAL);
		this.right_vertical= (Vertical) session.get(SurveyLogic.RIGHT_VERTICAL);
			
		Date start_time = new Date();
		
		this.session.put(SurveyLogic.START_TIME,start_time);
		
		return SUCCESS;
	
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user =user;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	@Override
	public void setSession(Map<String, Object> session) {
		
		System.out.println("INside set session: surveyaction" + session);
		
	    this.session = session;
	  }

	@Override
	public void setServletContext(ServletContext arg0) {
		// TODO Auto-generated method stub
		
		
		this.servletContext=arg0;
	}
}